﻿var db = require('bookshelf').bookshelf;
var Database = require('../app/database');
var Router = require('../app/router');
var moment = require('moment');
var util = require('util');
var http = require('http');
var TemplateBuilder = require('../app/template_builder');

var MemberController = module.exports = {};

log = function(msg) {
    //console.log(new Date().toLocaleTimeString() + ' [member_controller]: ' + msg);
};

MemberController.GroupUrls = [];

MemberController.initialize = function(router) {
	router
	.add({ Method: router.Methods.GET, URL: 'members/memberships', Authorize: router.Access.User, Handler: MemberController.updateMembersMemberships })
	.add({ Method: router.Methods.GET, URL: 'members/:id', Authorize: router.Access.User, Handler: MemberController.getMember })
	.add({ Method: router.Methods.GET, URL: 'members', Authorize: router.Access.User, Handler: MemberController.getMembers })
	.add({ Method: router.Methods.POST, URL: 'members/servers/:id', Authorize: router.Access.Owner, Handler: MemberController.postMemberRights })
	.add({ Method: router.Methods.DELETE, URL: 'members/:id', Authorize: router.Access.Owner, Handler: MemberController.deleteMember })
	log('initialize.js: ' + util.inspect(router,false,null));
};

MemberController.getMembers = function(req, res) {
    log('getMembers: ' + req.originalUrl + ' : ' + util.inspect(req.body, { showHidden: true, depth: null }));
    log('getMembers: ' + req.originalUrl + ' : ' + util.inspect(req.query, { showHidden: true, depth: null }));
    
    new Database.Collections.Members()
		.fetch({withRelated: ['rights']})
		.then(function(resp) {
		    res.json(200, resp);
		    log('replied: ' + util.inspect(resp, false, null));
		});
};

MemberController.getMember = function(req, res) {
	log('getMember: ' + req.originalUrl);
	new Database.Models.Member({member_id: req.params.id})
		.fetch({withRelated: ['rights']})
		.then(function(resp) {
			res.json(200, resp);
			log('replied: ' + util.inspect(resp,false,null));
		});
};

MemberController.deleteMember = function(req, res) {
	log('deleteMember: ' + req.originalUrl);
	new Database.Models.Member({member_id: req.params.id})
		.destroy()
		.then(function(resp) {
			res.json(200, resp);
			log('replied: ' + util.inspect(resp,false,null));
		});
};

MemberController.postMemberRights = function(req, res) {
	log('postMemberRights: ' + req.originalUrl + ' : ' + util.inspect(req.body, { showHidden: true, depth: null }));
    if (req.session.user.role < Router.Admin) {
        res.send(401,null);
    } else {
	    if (req.body && req.params && req.params.id) {
            var server_id = req.params.id;
            var isArray = (req.body instanceof Array);
		    var memberArray = [].concat( req.body );
		    log('memberArray: ' + util.inspect(memberArray,false,null));
		    var isValid = true;
            var member_rights = [];
		    for (var index = 0; index < memberArray.length; ++index) {
                var member = memberArray[index];
                if (member.rights != null && (member.rights instanceof Array)) {
                    for (var j = 0; j < member.rights.length; ++j) {
                        if (member.rights[j].server_id == server_id) {
                            member.rights[j].member_id = member.member_id;
                            member_rights.push(member.rights[j]);
                            break;
                        };
                    };
                };
            };
            if (member_rights && member_rights.length > 0) {
                saveMemberRightsForServer(server_id, member_rights);
                res.send(200,memberArray);
            } else {
		        res.send(500,{ status: 500, type: 'Resource', message: 'No rights to save' });
            };
	    } else {
		    res.send(500,{ status: 500, type: 'Resource', message: 'Argument not valid' });
	    };
    };
};

saveMemberRightsForServer = function(server_id, member_rights){
	log('saveMemberRightsForServer: ' + server_id + ' : ' + util.inspect(member_rights, { showHidden: true, depth: null }));
    if (member_rights && server_id && member_rights.length > 0) {
        var memberRights = [];
		for (var index = 0; index < member_rights.length; ++index) {
            saveMemberRights(member_rights[index], function(item) {
                log('saveMemberRightsForServer: Saved Item: ' + util.inspect(item, { showHidden: true, depth: null }));
                memberRights.push(item);
                if (memberRights.length >= member_rights.length) {
                    TemplateBuilder.execute(server_id).then(function(value){
                        log('Template Builder is done');
                    });
                };
            });
        };
    };
};

saveMemberRights = function(rights, callback) {
    rights.last_datetime = moment().format(moment.application_dateformat);
    var qb = new Database.Models.MemberRight().query();
    qb.where({member_id : rights.member_id, server_id: rights.server_id})
    .select()
    .then(function(resp){
        if (resp != null && resp.length > 0) {
            if (resp.length == 1) {
                var right = resp[0];
                if (right.rights_list != rights.rights_list) {
                    new Database.Models.MemberRight(right).set(rights).save().then(callback);
                } else {
                    callback(resp);
                };
            } else {
                log('saveMemberRights: ERROR! More than one result: ' + util.inspect(resp, { showHidden: true, depth: null }));
                callback({});
            };
        } else {
            new Database.Models.MemberRight(rights).save().then(callback);
        };
    });
};

MemberController.updateMembersMemberships = function(req, res) {
	log('updateMembersMemberships: ' + req.originalUrl + ' : ' + util.inspect(req.body, { showHidden: true, depth: null }));
    var method = 'GET';
    //var dataString = JSON.stringify(data);
    var headers = {};
    var responseCount = 0;
    var errors = [];
    for (var i = 0; i < MemberController.GroupUrls.length; i++) {
        var host = MemberController.GroupUrls[i];
  
        http.get(host, function(extres) {
            log("Got response: " + util.inspect(extres, { showHidden: true, depth: 2 }));
            var responseString = '';
            extres.on("data", function(chunk) {
                responseString += chunk;
            });
            extres.on('end', function () {
                responseCount++;
                log('Response End (' + responseCount + '): ' + responseString);
                if (responseString != null && responseString.length > 0) {
                    var responseObject = JSON.parse(responseString);
                    if (responseObject != null && (responseObject instanceof Array)) {
                        saveMembersMemberships(responseObject);
                    } else {
                         errors.push(extres.req.path + ': External URL gave an invalid result');
                    };
                } else {
                   errors.push(extres.req.path + ': External URL gave an empty result');
                };
                if (responseCount >= MemberController.GroupUrls.length) {
                    res.json(200, {success: true, count: responseCount, errors: errors});
                };
            });
        }).on('error', function(e) {
            responseCount++;
            log("Got error: " + e.message);
            errors.push(e.message);
            if (responseCount >= MemberController.GroupUrls.length) {
                res.json(200, {success: true, count: responseCount, errors: errors});
            };
        });
    };
};

saveMembersMemberships = function(members) {
    if (members != null && (members instanceof Array)) {
        for (var i = 0; i < members.length; i++) {
            var input = {
                member_name: members[i].name,
                member_rank: members[i].rank,
                membership_id: members[i].group,
                game_id: members[i].games.A3,
                last_datetime: moment().format(moment.application_dateformat),
            };
            saveOrUpdateMember(input);
        };
    };
};

saveOrUpdateMember = function(input) {
    var qb = new Database.Collections.Members().query(function(qb) {
        qb.where({member_name : input.member_name})
    }) 
    .fetch()
    .then(function(resp){
        if (resp != null && resp.length > 0) {
            if (resp.length == 1) {
                var member =  resp.at(0);
                if (member.member_rank != input.member_rank
                    || member.game_id != input.game_id
                    || member.membership_id != input.membership_id) {
                    member.set(input).save();
                };
            };
        } else {
            new Database.Models.Member(input).save();
        };
    });
};